﻿using Autofac;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyModel;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Yz.Cache;
using Yz.Core.Base;
using Yz.DataAccess.ModelMapper;

namespace Yz.Mvc.Modules
{
    public class AutofacModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder containerBuilder)
        {
            #region 实现接口IDependency 的自动注入
            var baseType = typeof(IDependency);
            var assemblys = new List<Assembly>();
            var asmNameList = DependencyContext.Default.CompileLibraries.Where(p => p.Name.Contains("Yz.")).Select(p => p.Name).ToList();
            foreach (var item in asmNameList)
            {
                var asm = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(item));
                assemblys.Add(asm);
            }
            containerBuilder.RegisterAssemblyTypes(assemblys.ToArray())
                  .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                  .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).AsImplementedInterfaces().InstancePerLifetimeScope();
            #endregion

            #region autoMapper注入 
            containerBuilder.RegisterType<Mapper>()
            .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).As<IMapper>()
            .InstancePerLifetimeScope();
            #endregion

            #region 缓存注入 (手动注入) 
            containerBuilder.RegisterType<CacheManagerUitility>()
          .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).As<ICacheUitility>()
          .InstancePerLifetimeScope();
            #endregion
            containerBuilder.Register<IConfigurationProvider>(ctx => new MapperConfiguration(x =>
            {
                x.AddProfile<SourceProfileApi>();
                x.AddProfile<SourceProfileVm>();
            })).PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).InstancePerLifetimeScope();

        
            var assembly = GetType().GetTypeInfo().Assembly;
            var builder = new ContainerBuilder();
            var manager = new ApplicationPartManager();
            manager.ApplicationParts.Add(new AssemblyPart(assembly));
            manager.FeatureProviders.Add(new ControllerFeatureProvider());
            var feature = new ControllerFeature();
            manager.PopulateFeature(feature);
            builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
            builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).AsImplementedInterfaces().InstancePerLifetimeScope();






        }
    }
}
